home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
strategy
/
vga_card.000
/
vga_cardgames-1.3.1.tar
/
vga_cardgames
/
splinux.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-26
|
13KB
|
551 lines
/*
* Spider
*
* Copyright (C) Evan Harris, 1993, 1994, 1995.
*
* Permission is granted to freely redistribute and modify this code,
* providing the author(s) get credit for having written it.
*/
#include <stdlib.h>
#include <stdio.h>
#include <vga.h>
#include <vgamouse.h>
#include "vga16.h"
#include "mouse.h"
#include "key.h"
#include "spider.h"
#define SP_SCREENMODE G640x480x16
#define SP_SCREENWIDTH 640
#define SP_SCREENHEIGHT 480
#define SP_TEXTFG 1
#define SP_TEXTBG 0
#define SP_BUTTONFG 2
#define SP_BUTTONBG 6
#define SP_MOUSEFG 5
#define SP_MOUSEDARKFG 2
#define SP_OUTLINE 6
#define NUMCARDIMAGES 52
#define CARDACTUALWIDTH 53
#define CARDIMAGEWIDTH 56
#define CARDIMAGEHEIGHT 80
#define VERSION "SPIDER\n v1.3"
#ifndef CARDSFILE
#define CARDSFILE "Cards56x80"
#endif
#ifndef CARDSMOUSESAMPLERATE
#define CARDSMOUSESAMPLERATE MOUSE_DEFAULTSAMPLERATE
#endif
#define USLEEP_TIME 30000
#define CARDTOIMAGE(card) (card % NUMCARDIMAGES)
#define BITWIDTH CARDIMAGEWIDTH /* multiple of 8 */
#define BITHEIGHT CARDIMAGEHEIGHT
#define BITSHOWLEFT 24 /* multiple of 8 */
#define BITTOP 24
#define COLWIDTH BITWIDTH
#define TOPROWHEIGHT (BITHEIGHT + 4)
#define SP_QUITLEFT (SP_SCREENWIDTH - 80)
#define SP_QUITRIGHT (SP_QUITLEFT + 80)
#define SP_QUITBOTTOM 132
#define SP_QUITTOP (SP_QUITBOTTOM - 16)
#define SP_NEWGAMELEFT SP_QUITLEFT
#define SP_NEWGAMERIGHT SP_QUITRIGHT
#define SP_NEWGAMEBOTTOM 48
#define SP_NEWGAMETOP (SP_NEWGAMEBOTTOM - 16)
#define SP_RESTARTLEFT SP_QUITLEFT
#define SP_RESTARTRIGHT SP_QUITRIGHT
#define SP_RESTARTBOTTOM 76
#define SP_RESTARTTOP (SP_RESTARTBOTTOM - 16)
#define SP_UNDOLEFT SP_QUITLEFT
#define SP_UNDORIGHT SP_QUITRIGHT
#define SP_UNDOBOTTOM 104
#define SP_UNDOTOP (SP_UNDOBOTTOM - 16)
#define STOCKLEFT 0
#define STOCKTOP 0
#define FOUNDLEFT (2 * BITWIDTH)
#define FOUNDTOP 0
#define SP_PALETTESIZE 7
int palette[SP_PALETTESIZE * 3] = {
0x00, 0x20, 0x00, /* green */
0x3f, 0x3f, 0x3f, /* white */
0x00, 0x00, 0x00, /* black */
0x37, 0x00, 0x00, /* red */
0x00, 0x00, 0x20, /* blue */
0x3f, 0x3f, 0x00, /* yellow */
0x1a, 0x1a, 0x1a, /* grey */
};
#define MIN(a, b) ((a) < (b) ? (a) : (b))
static void LoadCards(char *file);
static long GetMouseButton(void);
static long WhileMouseButton(void);
static int ParsePos(long pos, int downcard, int buttonup);
static unsigned char ***imageCard;
static unsigned char **backCard;
static unsigned char **outlineCard;
static unsigned char *blankLine;
void
InitDisplay(int argc, char **argv)
{
vga_disabledriverreport();
vga_init();
#if !defined(CARDSMOUSE)
vga_setmousesupport(1);
#endif
if (vga_setmode(SP_SCREENMODE) != 0) {
fprintf(stderr, "Mode %s not available!\n",
vga_getmodename(SP_SCREENMODE));
exit(1);
}
#if defined(CARDSMOUSE)
mouse_init("/dev/mouse", vga_getmousetype(), CARDSMOUSESAMPLERATE);
mouse_setxrange(0, SP_SCREENWIDTH - 1);
mouse_setyrange(0, SP_SCREENHEIGHT - 1);
mouse_setwrap(MOUSE_NOWRAP);
#endif
vga16_init();
LoadCards(CARDSFILE);
blankLine = (unsigned char *)calloc(SP_SCREENWIDTH, sizeof(unsigned char));
if (blankLine == NULL) {
fprintf(stderr, "Error: cannot get memory for blankLine\n");
exit(1);
}
vga_setpalvec(0, SP_PALETTESIZE, &palette[0]);
vga16_text(SP_NEWGAMELEFT, SP_NEWGAMEBOTTOM, " NEW GAME ",
SP_BUTTONFG, SP_BUTTONBG);
vga16_text(SP_RESTARTLEFT, SP_RESTARTBOTTOM, " RESTART ",
SP_BUTTONFG, SP_BUTTONBG);
vga16_text(SP_UNDOLEFT, SP_UNDOBOTTOM, " UNDO ",
SP_BUTTONFG, SP_BUTTONBG);
vga16_text(SP_QUITLEFT, SP_QUITBOTTOM, " QUIT ",
SP_BUTTONFG, SP_BUTTONBG);
vga16_text(SP_SCREENWIDTH - 64, 200, VERSION, SP_TEXTFG, SP_TEXTBG);
}
static void
LoadCards(char *file)
{
int i, j, k, l, c, colour;
FILE *f;
f = fopen(file, "r");
if (f == NULL) {
fprintf(stderr, "Cannot find '%s'\n", file);
exit(1);
}
imageCard = (unsigned char ***)malloc(NUMCARDIMAGES
* sizeof(unsigned char **));
if (imageCard == NULL) {
fprintf(stderr, "Error: cannot get memory for imageCard\n");
exit(1);
}
for (i = 0; i < NUMCARDIMAGES; i++) {
imageCard[i] = (unsigned char **)malloc(CARDIMAGEHEIGHT
* sizeof(unsigned char *));
if (imageCard == NULL) {
fprintf(stderr, "Error: cannot get memory for imageCard[%d]\n",
i);
exit(1);
}
for (j = 0; j < CARDIMAGEHEIGHT; j++) {
imageCard[i][j] = (unsigned char *)malloc(CARDIMAGEWIDTH
* sizeof(unsigned char));
if (imageCard[i][j] == NULL) {
fprintf(stderr,
"Error: cannot get memory for imageCard[%d][%d]\n",
i, j);
exit(1);
}
if (SUIT(i) == SPADES || SUIT(i) == CLUBS) {
colour = 2;
} else {
colour = 3;
}
if (TYPE(i) < JACK) {
for (k = 0; k < CARDIMAGEWIDTH / 8; k++) {
if ((c = getc(f)) == EOF) {
fprintf(stderr, "Unexpected EOF in '%s'\n", file);
exit(1);
}
for (l = 0; l < 8; l++) {
imageCard[i][j][8 * k + l] =
(c & 1 << (7 - l)) ? colour : 1;
}
}
for (k = CARDACTUALWIDTH; k < CARDIMAGEWIDTH; k++) {
imageCard[i][j][k] = 0;
}
} else {
for (k = 0; k < CARDIMAGEWIDTH / 2; k++) {
if ((c = getc(f)) == EOF) {
fprintf(stderr, "Unexpected EOF in '%s'\n", file);
exit(1);
}
imageCard[i][j][2 * k] = (unsigned char)c >> 4;
imageCard[i][j][2 * k + 1] = (unsigned char)c & 0xf;
}
}
}
}
fclose(f);
backCard = malloc(CARDIMAGEHEIGHT * sizeof(unsigned char *));
outlineCard = malloc(CARDIMAGEHEIGHT * sizeof(unsigned char *));
if (backCard == NULL || outlineCard == NULL) {
fprintf(stderr, "Error: cannot get memory for cards");
exit(1);
}
for (i = 0; i < CARDIMAGEHEIGHT; i++) {
backCard[i] = malloc(CARDIMAGEWIDTH * sizeof(unsigned char));
outlineCard[i] = calloc(CARDIMAGEWIDTH, sizeof(unsigned char));
if (backCard[i] == NULL || outlineCard[i] == NULL) {
fprintf(stderr, "Error: cannot get memory for cards");
exit(1);
}
}
for (i = 0; i < CARDACTUALWIDTH; i++) {
outlineCard[0][i] = SP_OUTLINE;
outlineCard[CARDIMAGEHEIGHT - 1][i] = SP_OUTLINE;
}
for (i = 0; i < CARDIMAGEHEIGHT; i++) {
outlineCard[i][0] = SP_OUTLINE;
outlineCard[i][CARDACTUALWIDTH - 1] = SP_OUTLINE;
}
for (i = 0; i < CARDIMAGEHEIGHT; i++) {
for (j = 0; j < CARDACTUALWIDTH; j++) {
if ((i / 4) % 2 == (j / 4) % 2) {
backCard[i][j] = 4;
} else {
backCard[i][j] = 1;
}
}
for (; j < CARDIMAGEWIDTH; j++) {
backCard[i][j] = 0;
}
}
}
static unsigned char columnTop[COLUMNS];
/* We redisplay a whole column, rather than do anything tricky. */
void
DisplayColumn(short col)
{
unsigned char **image;
int card, length, row, height, line;
int bittop = BITTOP;
if (col == STOCK || col == PILE) {
DisplayStockPile();
return;
}
for (card = column[col], length = 0; card != NOCARD; card = next[card])
length++;
if (length > 0 && (SP_SCREENHEIGHT - TOPROWHEIGHT) / length < bittop)
bittop = (SP_SCREENHEIGHT - TOPROWHEIGHT) / length;
columnTop[col] = bittop;
card = column[col];
row = TOPROWHEIGHT;
col = col * COLWIDTH;
while (card != NOCARD && row < SP_SCREENHEIGHT - 1) {
if (hidden[card])
image = backCard;
else
image = imageCard[CARDTOIMAGE(card)];
if (next[card] == NOCARD)
height = BITHEIGHT;
else
height = bittop;
if (row + height >= SP_SCREENHEIGHT)
height -= row + height - SP_SCREENHEIGHT + 1;
for (line = 0; line < height; line++) {
vga16_drawscansegment(image[line], col, row + line, BITWIDTH);
}
row += height;
card = next[card];
}
for (; row < SP_SCREENHEIGHT; row++) {
vga16_drawscansegment(blankLine, col, row, BITWIDTH);
}
return;
}
void
DisplayStockPile()
{
unsigned char **card;
int line;
if (stock == NOCARD) {
card = outlineCard;
} else {
card = backCard;
}
for (line = 0; line < CARDIMAGEHEIGHT; line++) {
vga16_drawscansegment(card[line], STOCKLEFT, STOCKTOP + line,
BITWIDTH);
}
}
void
DisplayFoundations()
{
unsigned char **card;
int i, line, foundleft;
foundleft = FOUNDLEFT;
for (i = 0; i < NUMSUITS; i++) {
if (foundation[i] == 0) {
card = outlineCard;
} else {
card = imageCard[CARD(i % 4, ACE)];
}
for (line = 0; line < CARDIMAGEHEIGHT; line++) {
vga16_drawscansegment(card[line], foundleft, FOUNDTOP + line,
BITWIDTH);
}
foundleft += BITWIDTH;
}
}
short
GetCmd()
{
int c, c1;
for (c = NOCARD; c == NOCARD;) {
c = GetMouseButton();
c1 = WhileMouseButton();
if (c >= 0) {
c = ParsePos(c, -1, 0);
c1 = ParsePos(c1, c, 1);
if (c == c1 && (c >= 0 || c == FROMSTOCK)) {
return c;
}
if (c >= 0 && c1 == TOFOUNDATION) {
return TOHINT(FOUNDATION) | c;
}
if (c >= 0 && ISCOLSPEC(c1)) {
return TOHINT(SPECTOCOL(c1)) | c;
}
c = NOCARD;
}
}
return c;
}
static int oldx = -1, oldy, oldcolour[40];
static long
GetMouseButton()
{
int x, y, button, key;
x = mouse_getx();
y = mouse_gety();
if (x != oldx || y != oldy) {
if (oldx != -1) {
RestoreUnderMousePointer(oldx, oldy, SP_SCREENWIDTH, SP_SCREENHEIGHT, oldcolour);
}
SaveUnderMousePointer(x, y, SP_SCREENWIDTH, SP_SCREENHEIGHT, oldcolour);
RenderMousePointer(x, y, SP_MOUSEFG, SP_MOUSEDARKFG, SP_SCREENWIDTH, SP_SCREENHEIGHT);
oldx = x;
oldy = y;
}
for (;;) {
usleep(USLEEP_TIME); /* don't chew up as much CPU */
if (mouse_update()) {
x = mouse_getx();
y = mouse_gety();
button = mouse_getbutton();
if (x != oldx || y != oldy) {
if (oldx != -1) {
RestoreUnderMousePointer(oldx, oldy, SP_SCREENWIDTH, SP_SCREENHEIGHT, oldcolour);
}
SaveUnderMousePointer(x, y, SP_SCREENWIDTH, SP_SCREENHEIGHT, oldcolour);
RenderMousePointer(x, y, SP_MOUSEFG, SP_MOUSEDARKFG, SP_SCREENWIDTH, SP_SCREENHEIGHT);
oldx = x;
oldy = y;
}
if (button & MOUSE_LEFTBUTTON) {
break;
}
}
if ((key = key_getkey()) != -1) {
switch (key) {
case 'n':
case 'N':
return NEWGAME;
case 'r':
case 'R':
return RESTART;
case 'u':
case 'U':
return UNDO;
case 'q':
case 'Q':
return QUIT;
case '\014':
vga16_redrawscreen();
break;
default:
break;
}
}
}
if (x >= SP_NEWGAMELEFT && x < SP_NEWGAMERIGHT
&& y > SP_NEWGAMETOP && y <= SP_NEWGAMEBOTTOM) {
return NEWGAME;
}
if (x >= SP_RESTARTLEFT && x < SP_RESTARTRIGHT
&& y > SP_RESTARTTOP && y <= SP_RESTARTBOTTOM) {
return RESTART;
}
if (x >= SP_UNDOLEFT && x < SP_UNDORIGHT
&& y > SP_UNDOTOP && y <= SP_UNDOBOTTOM) {
return UNDO;
}
if (x >= SP_QUITLEFT && x < SP_QUITRIGHT
&& y > SP_QUITTOP && y <= SP_QUITBOTTOM) {
return QUIT;
}
return (x << 9) | y;
}
static long
WhileMouseButton()
{
int x, y, button;
for (;;) {
usleep(USLEEP_TIME); /* don't chew up as much CPU */
mouse_update();
x = mouse_getx();
y = mouse_gety();
button = mouse_getbutton();
if (x != oldx || y != oldy) {
if (oldx != -1) {
RestoreUnderMousePointer(oldx, oldy, SP_SCREENWIDTH, SP_SCREENHEIGHT, oldcolour);
}
SaveUnderMousePointer(x, y, SP_SCREENWIDTH, SP_SCREENHEIGHT, oldcolour);
RenderMousePointer(x, y, SP_MOUSEFG, SP_MOUSEDARKFG, SP_SCREENWIDTH, SP_SCREENHEIGHT);
oldx = x;
oldy = y;
}
if (!(button & MOUSE_LEFTBUTTON)) {
break;
}
}
if (oldx != -1) {
RestoreUnderMousePointer(oldx, oldy, SP_SCREENWIDTH, SP_SCREENHEIGHT, oldcolour);
}
oldx = -1;
return (x << 9) | y;
}
static int
ParsePos(long pos, int downcard, int buttonup)
{
int x, y, card, row, bittop;
x = pos >> 9;
y = pos & 0x1ff;
if (x >= STOCKLEFT && x < STOCKLEFT + BITWIDTH
&& y >= STOCKTOP && y < STOCKTOP + CARDIMAGEHEIGHT) {
return FROMSTOCK;
}
if (buttonup
&& x >= FOUNDLEFT && x < FOUNDLEFT + NUMSUITS * COLWIDTH
&& y >= FOUNDTOP && y < FOUNDTOP + CARDIMAGEHEIGHT) {
return TOFOUNDATION;
}
if (x / COLWIDTH > 9 || y < TOPROWHEIGHT) {
return NOCARD;
}
card = column[x / COLWIDTH];
bittop = columnTop[x / COLWIDTH];
row = TOPROWHEIGHT;
while (card != NOCARD) {
if ((next[card] != NOCARD && y >= row && y < row + bittop)
|| (next[card] == NOCARD && y >= row && y < row + BITHEIGHT)) {
if (!hidden[card] && (downcard == -1 || downcard == card)) {
return card;
}
}
card = next[card];
row += bittop;
}
if (buttonup) {
return COLTOSPEC(x / COLWIDTH);
}
return NOCARD;
}